為了方便後續觀察各種事件對地圖造成的影響,我們今天的目標是把地圖這個物件轉換成我們方便觀察的樣子,具體轉換方法如下 :
煞氣a刀賊
___紅寶 ___
參考以上作法,在 src/view
中實作一個 visualize 函式
import { GridItem, Map } from "./models/map";
import { transpose } from "./utils/array";
import { getPrintLength, padEnd } from "./utils/string";
export const visualize = (data: Map) => {
const rowToString = (row: GridItem[][]) => {
const rowHeight =
row
.map((item) => item.length)
.reduce((prev, next) => (next > prev ? next : prev), 1) + 1;
const getItemsWidth = (items: GridItem[]) =>
items
.map((item) => getPrintLength(item.name))
.reduce((prev, next) => (next > prev ? next : prev), 1);
const result = row.map((items) => {
const height = items.length;
const width = getItemsWidth(items);
const board = new Array(rowHeight)
.fill("")
.map((s, i) => padEnd(s, width, i == 0 ? "_" : " ")); // 空白模板
for (let i = 0; i < height; i++) {
board[i] = padEnd(items[i].name, width, " ");
}
return board;
});
return (
transpose(result)
.reverse()
.map((items) => items.join(""))
.join("\n") + "\n"
);
};
return data.grid.map((row) => rowToString(row)).join("");
};
最後附上一些工具函式
// src\utils\array
export const transpose = <T>(matrix: T[][]) =>
matrix[0].map((_, colIndex) => matrix.map((row) => row[colIndex]));
// src\utils\string
const isFullWidth = (char: string) => {
const code = char.charCodeAt(0);
return (
(code >= 0xff01 && code <= 0xff60) ||
(code >= 0xffe0 && code <= 0xffe6) ||
(code >= 0x4e00 && code <= 0x9fff)
);
};
export const getPrintLength = (str: string) =>
Array.from(str).reduce<number>(
(sum, next) => sum + (isFullWidth(next) ? 2 : 1),
0
);
export const padEnd = (str: string, width: number, fill: string) => {
const strWidth = getPrintLength(str);
return str + (strWidth < width ? fill.repeat(width - strWidth) : "");
};
有了這些函式我們就可以很方便的觀察地圖的狀態變化